using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using BG.Core;
using UnityEngine;
using UnityEngine.Scripting;

[assembly: Preserve]

namespace Huatuo
{
    enum IntEnum : int
    {
        A,
        B,
    }

    public class RefTypes : MonoBehaviour
    {
        void RefUnityEngine()
        {
            Instantiate<GameObject>(null);
            Instantiate<GameObject>(null, null);
            Instantiate<GameObject>(null, null, false);
            Instantiate<GameObject>(null, new Vector3(), new Quaternion());
            Instantiate<GameObject>(null, new Vector3(), new Quaternion(), null);
            this.gameObject.AddComponent<RefTypes>();
            gameObject.AddComponent(typeof(RefTypes));
        }

        void RefNullable()
        {
            // nullable
            int? a = 0;
            object b = a;
        }

        void RefContainer()
        {
            new List<object>()
            {
                new Dictionary<int, int>(),
                new Dictionary<int, long>(),
                new Dictionary<int, object>(),
                new Dictionary<long, int>(),
                new Dictionary<long, long>(),
                new Dictionary<long, object>(),
                new Dictionary<object, long>(),
                new Dictionary<object, object>(),
                new SortedDictionary<int, long>(),
                new SortedDictionary<int, object>(),
                new SortedDictionary<long, int>(),
                new SortedDictionary<long, object>(),
                new HashSet<int>(),
                new HashSet<long>(),
                new HashSet<object>(),
                new HashSet<Vector2>(),
                new HashSet<Vector3>(),
                new List<int>(),
                new List<long>(),
                new List<float>(),
                new List<double>(),
                new List<object>(),
                new List<Vector2>(),
                new List<Vector3>(),
                new Queue<int>(),
                new Queue<long>(),
                new Queue<float>(),
                new Queue<double>(),
                new Queue<object>(),
                new Queue<Vector2>(),
                new Queue<Vector3>(),
                new Stack<int>(),
                new Stack<long>(),
                new Stack<float>(),
                new Stack<double>(),
                new Stack<object>(),
                new Stack<Vector2>(),
                new Stack<Vector3>(),
                new ValueTuple<int, int>(1, 1),
                new ValueTuple<long, long>(1, 1),
                new ValueTuple<object, object>(1, 1),
            };
        }

        class RefStateMachine : IAsyncStateMachine
        {
            public void MoveNext()
            {
                throw new NotImplementedException();
            }

            public void SetStateMachine(IAsyncStateMachine stateMachine)
            {
                throw new NotImplementedException();
            }
        }

        void RefBGTaskMethod()
        {
            var stateMachine = new RefStateMachine();

            var aw = BGTask.Create().GetAwaiter();
            var c1 = new AsyncBGTaskMethodBuilder();
            c1.Start(ref stateMachine);
            c1.AwaitOnCompleted(ref aw, ref stateMachine);
            c1.AwaitUnsafeOnCompleted(ref aw, ref stateMachine);

            var aw2 = BGTask<bool>.Create().GetAwaiter();
            var c2 = new AsyncBGTaskMethodBuilder<bool>();
            c2.Start(ref stateMachine);
            c2.AwaitOnCompleted(ref aw2, ref stateMachine);
            c2.AwaitUnsafeOnCompleted(ref aw2, ref stateMachine);

            var aw3 = BGTask<int>.Create().GetAwaiter();
            var c3 = new AsyncBGTaskMethodBuilder<int>();
            c3.Start(ref stateMachine);
            c3.AwaitOnCompleted(ref aw3, ref stateMachine);
            c3.AwaitUnsafeOnCompleted(ref aw3, ref stateMachine);

            var aw4 = BGTask<long>.Create().GetAwaiter();
            var c4 = new AsyncBGTaskMethodBuilder<long>();
            c4.Start(ref stateMachine);
            c4.AwaitOnCompleted(ref aw4, ref stateMachine);
            c4.AwaitUnsafeOnCompleted(ref aw4, ref stateMachine);

            var aw5 = BGTask<float>.Create().GetAwaiter();
            var c5 = new AsyncBGTaskMethodBuilder<float>();
            c5.Start(ref stateMachine);
            c5.AwaitOnCompleted(ref aw5, ref stateMachine);
            c5.AwaitUnsafeOnCompleted(ref aw5, ref stateMachine);

            var aw6 = BGTask<double>.Create().GetAwaiter();
            var c6 = new AsyncBGTaskMethodBuilder<double>();
            c6.Start(ref stateMachine);
            c6.AwaitOnCompleted(ref aw6, ref stateMachine);
            c6.AwaitUnsafeOnCompleted(ref aw6, ref stateMachine);

            var aw7 = BGTask<object>.Create().GetAwaiter();
            var c7 = new AsyncBGTaskMethodBuilder<object>();
            c7.Start(ref stateMachine);
            c7.AwaitOnCompleted(ref aw7, ref stateMachine);
            c7.AwaitUnsafeOnCompleted(ref aw7, ref stateMachine);

            var aw8 = BGTask<IntEnum>.Create().GetAwaiter();
            var c8 = new AsyncBGTaskMethodBuilder<IntEnum>();
            c8.Start(ref stateMachine);
            c8.AwaitOnCompleted(ref aw8, ref stateMachine);
            c8.AwaitUnsafeOnCompleted(ref aw8, ref stateMachine);
        }

        void RefBGTaskCompletedMethod()
        {
            var stateMachine = new RefStateMachine();

            var aw = new BGTaskCompleted().GetAwaiter();
            var c1 = new AsyncBGTaskCompletedMethodBuilder();
            c1.Start(ref stateMachine);
            c1.AwaitOnCompleted(ref aw, ref stateMachine);
            c1.AwaitUnsafeOnCompleted(ref aw, ref stateMachine);
        }
        
        void RefBGTaskVoidMethod()
        {
            var stateMachine = new RefStateMachine();

            var aw = BGTask.Create().GetAwaiter();
            var c1 = new AsyncBGVoidMethodBuilder();
            c1.Start(ref stateMachine);
            c1.AwaitOnCompleted(ref aw, ref stateMachine);
            c1.AwaitUnsafeOnCompleted(ref aw, ref stateMachine);
        }
    }
}